Falco: detección de amenazas en tiempo de ejecución con eBPF

Pantalla con editor mostrando código en fondo oscuro representando monitorización kernel

La detección de amenazas ha vivido dos eras: perímetro (firewalls, IDS de red) y endpoint (EDR en laptops). Contenedores y Kubernetes rompen las asunciones de ambas: el perímetro es difuso, los endpoints son efímeros. Falco, proyecto graduado de la CNCF, ataca el problema desde otra dirección: observar el kernel y alertar cuando alguien ejecuta comportamientos que no encajan.

Este artículo cubre qué hace Falco bien, qué no hace, y qué necesita alrededor para ser útil en operación.

Qué mira Falco

Falco engancha el kernel de Linux (vía eBPF o un módulo tradicional) y observa syscalls en tiempo real. Cada syscall — open, execve, connect, setuid — pasa por sus reglas. Si alguna dispara, Falco emite un evento.

Ejemplos de reglas por defecto:

  • Shell en contenedor: se abre una shell interactiva dentro de un contenedor en producción.
  • Escritura en /etc: un proceso modifica archivos sensibles.
  • Binario ejecutado desde /tmp: patrón clásico de dropper.
  • Conexión saliente inesperada: el contenedor intenta llamar a un IP desconocido.
  • Cambio de privilegios: un proceso escala a root sin ser su CMD habitual.

La potencia está en la granularidad: no es “el contenedor hizo algo malo”, es “el PID 1234 llamó a execve con argv=/bin/sh dentro del namespace de este pod, y eso no coincide con la baseline”.

Arquitectura eBPF vs módulo kernel

Falco soporta dos drivers:

  • eBPF moderno (CO-RE, desde Falco 0.34+): portable entre kernels, sin compilación, sin módulo cargado. Es el recomendado.
  • eBPF legacy: requiere headers del kernel en build-time.
  • Módulo kernel: el más antiguo. Aún útil en kernels que no soportan eBPF CO-RE, pero cada vez menos relevante.

Para Debian 12+, Ubuntu 22.04+, Amazon Linux 2023, RHEL 9+ el driver eBPF moderno funciona sin pelear. En kernels muy antiguos (<5.8) puede que necesites el módulo.

Reglas: el 80/20

Falco viene con falco_rules.yaml con unas 80 reglas out-of-the-box. Lo razonable:

  • Empezar con lo default. Ver qué genera ruido en tu entorno real los primeros 2-3 días.
  • Silenciarfalsos positivos comunes**. Tu backup copia archivos en /etc/cron.d — eso parece “escritura en ruta sensible” pero es legítimo.
  • Añadir reglas específicas de tu stack (ej: “nadie ejecuta kubectl exec fuera de horario de oficina”).
  • Invertir el resto en runbooks para los eventos reales.

Reglas útiles más allá del default:

- rule: Acceso a credenciales AWS
  desc: Acceso al directorio .aws o al metadata EC2
  condition: (fd.name in (~/.aws/credentials) or fd.name=169.254.169.254)
  output: "Posible extracción de credenciales AWS (user=%user.name)"
  priority: WARNING

Las reglas se escriben en un DSL propio — simple pero potente. El tutorial oficial cubre lo esencial.

Salida: SIEM y notificación

Falco genera eventos JSON. Lo que haces con ellos define la utilidad:

  • Falcosidekick (companion oficial): router de eventos a Slack, PagerDuty, Elasticsearch, Loki, Alertmanager, y decenas más.
  • Loki + Grafana: eventos como logs, alertas vía Grafana Alerting. Bueno para equipos que ya tienen la pila.
  • SIEM (Splunk, Sentinel, Elastic Security): Falco como fuente de detección entre otras.

El error común es dejar los eventos en /var/log/falco.log y nunca mirarlos. Sin ruteo a un lugar donde se revisen, Falco es ruido local.

Despliegue en Kubernetes

En K8s, Falco se despliega como DaemonSet — un pod por nodo, con acceso privilegiado al kernel del nodo.

  • Helm chart oficial: falcosecurity/falco. Incluye opciones para driver, reglas, export de eventos.
  • Requiere un securityContext privilegiado o hostPID + hostNetwork + capacidades específicas. Eso es una superficie de riesgo — Falco tiene más privilegios que casi cualquier cosa en el cluster.
  • Recursos: ~200MB RAM, 0.1-0.5 CPU por nodo en reposo. Picos en arranques masivos de pods.
  • Actualización frecuente: las reglas de amenazas cambian; mantén Falco al día.

Dónde Falco no llega

Ser honesto sobre los límites:

  • Ataques en memoria (sin syscalls observables) pasan por debajo del radar.
  • Comportamiento malicioso dentro de syscalls normales (ej: exfil via HTTPS normal a un C2) requiere reglas específicas contra el destino.
  • Cryptojacking sofisticado puede evitar patrones obvios.
  • Zero-days en el kernel que subvierten eBPF.

Falco no es un antivirus ni un WAF. Es detección de anomalías en syscalls. Complementa otras capas; no las sustituye.

Integración con Kubernetes Audit

Además de syscalls, Falco puede consumir logs del Kubernetes API audit log y aplicar reglas sobre acciones de API (ej: “alguien creó un Secret con un nombre sospechoso”). Cubre la capa de control-plane que los syscalls no tocan.

Útil para detectar:

  • Cambios en RBAC fuera de horario.
  • Creación masiva de pods privilegiados.
  • Acceso a Secrets que no son usuales.

Operación: lo que duele

Un año operando Falco en producción deja lecciones:

  • Actualizar reglas sin versionar es caótico. Mantener rulesets en Git con CI que los valida.
  • Drift entre Falco y kernel. Cada actualización mayor del kernel puede romper eBPF CO-RE por edge cases.
  • Alert fatigue. Si el 90% de alertas son benignas, el 10% importante se pierde. Invierte en refinar reglas.
  • Coste en nodos densos. 200 pods/nodo = muchos syscalls. Monitorizar uso de CPU de Falco.
  • Turnover del equipo. Si nadie entiende las reglas, nadie las refina. Documentar.

Cuándo adoptar Falco

Claramente útil:

  • Kubernetes en producción con pods de terceros o multi-tenant.
  • Cumplimiento que exige monitorización runtime (PCI DSS, SOC 2 maduro).
  • Equipos con SOC que pueden triaje de eventos.

Marginal o demasiado:

  • Un nodo Docker solo. Falco es demasiado para ese caso; más simple un auditd bien configurado.
  • Equipos sin proceso de respuesta. Las alertas sin respuesta son teatro.

Conclusión

Falco es una pieza madura y de código abierto para detección runtime en entornos cloud-native. Requiere inversión en operación — reglas afinadas, rutado de eventos, respuesta — pero a cambio ofrece visibilidad que las capas tradicionales no alcanzan. Antes de adoptar, pregunta si tu equipo tiene la capacidad de procesar sus eventos; si la respuesta es no, priorízala antes que el despliegue. Detectar sin responder es ruido; detectar con respuesta es defensa real.

Síguenos en jacar.es para más sobre seguridad runtime, eBPF y operación de Kubernetes.

Entradas relacionadas